

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "omci_adpt_common.h"
#include "omci_adpt_general.h"

#include "omci_me_layer3_data_services.h"
#include "omci_me_mac_bridge.h"
#include "omci_me_vlan.h"


/************************************************************************
*                  D E F I N E S   &   C O N S T A N T S
*************************************************************************
*/

#define IP_OPTION_DHCP_MASK		(1<<0)
#define IP_OPTION_ENABLE_PING_RESPONSE_MASK (1<<1)
#define IP_OPTION_ENABLE_TRACERT_RESPONSE_MASK (1<<2)
#define IP_OPTION_ENABLE_IPSTACK_MASK (1<<3)
#define IP_HOST_MAC_PATH "/etc/mac.conf"

#define IP_HOST_PING_TEST			0x1
#define IP_HOST_TRACEROUTE_TEST	0x2
#define IP_HOST_VENDOR_TEST 		0x8
#define IP_HOST_TEST_PING_PATH		"/tmp/omci/ipHostPingTest_stat"
#define IP_HOST_TEST_TRACEROUTE_PATH	"/tmp/omci/ipHostTracerouteTest_stat"
#define MAX_BUF_LEN 		1024
#define IMCOMPLETE_STR		"0 packets received"
#define ICMP_SEQ0			"icmp_seq=0"
#define ICMP_SEQ1			"icmp_seq=1"
#define ICMP_SEQ2			"icmp_seq=2"
#define ICMP_SEQ3			"icmp_seq=3"

#define MAX_ARG_NUM	3
#define MAX_NODE_NAME 16
#define WAN	"Wan"
#define WAN_PVC "PVC"
#define IPHOST_NODE "XPON_IPHost%d"
#define COMMIT_WAN_ATTR "commitWan"
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_CMCC)
#define PVC_NUM 1
#else/*TCSUPPORT_COMPILE*/
#define PVC_NUM 8
#endif/*TCSUPPORT_COMPILE*/

#define TMP_IF_PATH "/tmp/wanInfo"
#define MAX_SMUX_NUM 8
#define WAN_INTERFACE "Entry"

#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_CT)
#define WAN_IF_PATH "/var/run/"
#define WANNODE_FORMAT "Wan_PVC%d_Entry%d"
#define IFNAME_FORMAT "nas%d_%d"
#else/*TCSUPPORT_COMPILE*/
#define WANNODE_FORMAT "Wan_PVC%d"
#define IFNAME_FORMAT "nas%d"
#define WANDEV_INFO_FORMAT "DeviceInfo_PVC%d"
#endif/*TCSUPPORT_COMPILE*/

#define OMCI_INVALID_IPHOST_ID "0xFF"

omciIPhostWanInfo_t omciIPHostWanInfo[2]; 
omciIPhostWanInfo_t omciOldTR069Info; 
omciIPhostWanInfo_t omciOldVOICEInfo; 

int omciWanType [2] = {WAN_SERVICELIST_MAX,WAN_SERVICELIST_MAX};
char tr69wan[OMCI_LAYER3_STR_BUFF_SIZE]={0};

OMCI_IPHOST_INFO_t g_iphost_wan[MAX_IPHOST_WAN_NUM] = {{0},{0}};
OMCI_IPHOST_WEB_RCD_t g_web_rcd_info[E_WAN_SVC_TYPE_MAX] = {{0},{0}};
int commitWanTimer = INVALID_TIMERID;
int ipOptionId[MAX_IPHOST_WAN_NUM] = {0,0};
typedef struct IPHostConfig
{
	uint8_t ipOptions;
	uint16_t instId;
	char ifName[OMCI_LAYER3_ATR_BUFF_SIZE];
}IPHostConfig;
static struct IPHostConfig configData[MAX_IPHOST_WAN_NUM] = {{0},{0}};



extern omci_me_info_t getCurrentMeInfo(void);

extern omci_me_info_t getCurrentMeInfo(void);


omciPPPoECfgAttrInfo_t omciPPPoEInfo;

char g_pppoe_wan[PPPOE_IF_TYPE_MAX+1][OMCI_LAYER3_STR_BUFF_SIZE] = {
    "PPPoE LLC",             //PPPOE_IF_TYPE_ENCAP
    "linkPPP",               //PPPOE_IF_TYPE_LINKMODE
    "Dynamic",               //PPPOE_IF_TYPE_PPPGETIP
    " ",                     //PPPOE_IF_TYPE_CONNECTION
    " ",                     //PPPOE_IF_TYPE_USERNAME
    " ",                     //PPPOE_IF_TYPE_PASSWORD
    "2",                     //PPPOE_IF_TYPE_ISP
    " ",                     //PPPOE_IF_TYPE_NATENABLE
    "1",                     //PPPOE_IF_TYPE_DHCPEN
    " ",                     //PPPOE_IF_TYPE_PPPUNIT
    " ",                     //PPPOE_IF_TYPE_IFNAME
    "Connect_Keep_Alive",    //PPPOE_IF_TYPE_CONNECTIONERROR
    " ",                     //PPPOE_IF_TYPE_CLOSEIFIDLE
    " ",                     //PPPOE_IF_TYPE_AUTHEN
    "INTERNET",              //PPPOE_IF_TYPE_SVC_LIST
    " ",                     //PPPOE_IF_TYPE_SRVNAME
    " "                     //PPPOE_IF_TYPE_MAX
};


/************************************************************************
*                  M A C R O S
*************************************************************************
*/    


/************************************************************************
*                  D A T A     T Y P E S
*************************************************************************
*/


/************************************************************************
*                  E X T E R N A L     D A T A   D E C L A R A T I O N S
*************************************************************************
*/



/************************************************************************
*                  F U N C T I O N   D E C L A R A T I O N S
*************************************************************************
*/

/*******************************************************************************************************************************
9.4.1: IP host config data

********************************************************************************************************************************/

int setIPHostConfigDataIPOptions(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int getIPHostConfigDataMACAddr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int setIPHostConfigDataIPAddr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int setIPHostConfigDataMask(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int setIPHostConfigDataGateway(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int setIPHostConfigDataPrimaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int setIPHostConfigDataSecondaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int getIPHostConfigDataCurAddr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int getIPHostConfigDataCurMask(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int getIPHostConfigDataCurGateway(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int getIPHostConfigDataCurPrimaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);
int getIPHostConfigDataCurSecondaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr);


/*******************************************************************************************************************************
9.4.2: IP host performance monitoring history data

********************************************************************************************************************************/



/*******************************************************************************************************************************
9.4.4: TCP/UDP performance monitoring history data

********************************************************************************************************************************/



/************************************************************************
*                  P U B L I C   D A T A
*************************************************************************
*/


/************************************************************************
*                  P R I V A T E   D A T A
*************************************************************************
*/


/*******************************************************************************************************************************
9.4.1: IP host config data

********************************************************************************************************************************/
#if defined(TCSUPPORT_PON_IP_HOST)
static attribute_func_t IPHostConfigDataIPOptionsFunc = {
	NULL,
	setIPHostConfigDataIPOptions
};
#endif

static attribute_func_t IPHostConfigDataMACAddrFunc = {
	getIPHostConfigDataMACAddr,
	NULL
};

static attribute_func_t IPHostConfigDataIPAddrFunc = {
	NULL,
	setIPHostConfigDataIPAddr
};

static attribute_func_t IPHostConfigDataMaskFunc = {
    NULL,
	setIPHostConfigDataMask
};

static attribute_func_t IPHostConfigDataGatewayFunc = {
	NULL,
	setIPHostConfigDataGateway
};

static attribute_func_t IPHostConfigDataPrimaryDNSFunc = {
	NULL,
	setIPHostConfigDataPrimaryDNS
};

static attribute_func_t IPHostConfigDataSecondaryDNSFunc = {
	NULL,
	setIPHostConfigDataSecondaryDNS
};

static attribute_func_t IPHostConfigDataCurAddrFunc = {
	getIPHostConfigDataCurAddr,
	NULL
};

static attribute_func_t IPHostConfigDataCurMaskFunc = {
	getIPHostConfigDataCurMask,
	NULL
};

static attribute_func_t IPHostConfigDataCurGatewayFunc = {
	getIPHostConfigDataCurGateway,
	NULL
};

static attribute_func_t IPHostConfigDataCurPrimaryDNSFunc = {
	getIPHostConfigDataCurPrimaryDNS,
	NULL
};

static attribute_func_t IPHostConfigDataCurSecondaryDNSFunc = {
	getIPHostConfigDataCurSecondaryDNS,
	NULL
};

omci_attr_dscp_t omci_attr_ip_host_cfg_op[]={
{0, "meId",						2,	ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&generalAttrFunc},
#ifdef TCSUPPORT_PON_IP_HOST
{1, "ip options",				1,	ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,	&IPHostConfigDataIPOptionsFunc},
#else
{1, "ip options",				1,	ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,	&generalAttrFunc},
#endif
{2, "mac addr",                 6,  ATTR_ACCESS_R,      ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,	&IPHostConfigDataMACAddrFunc},
{3, "onu identifier",           25, ATTR_ACCESS_R_W,    ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{4, "ip addr",                  4,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataIPAddrFunc},
{5, "mask",                     4,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataMaskFunc},
{6, "gateway",                  4,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataGatewayFunc},
{7, "primary dns",              4,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataPrimaryDNSFunc},
{8, "secondary dns",            4,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataSecondaryDNSFunc},
{9, "current addr",             4,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataCurAddrFunc},
{10, "current mask",            4,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataCurMaskFunc},
{11, "current gateway",         4,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataCurGatewayFunc},
{12, "current primary dns",     4,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataCurPrimaryDNSFunc},
{13, "current secondary dns",   4,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&IPHostConfigDataCurSecondaryDNSFunc},
{14, "domain name",             25, ATTR_ACCESS_R,      ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{15, "host name",               25, ATTR_ACCESS_R,      ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{16, "relay agent options",		2,  ATTR_ACCESS_R_W,	ATTR_FORMAT_UNSIGNED_INT, 	ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{255, "",                       0,  0,                              0,                          0,                      NULL}

};

omci_me_func_t omci_me_ip_host_cfg_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_ip_host_cfg_t omci_ip_host_cfg_attr_data = {0};

omci_attr_t omci_ip_host_cfg_attr ={
	(uint8_t *)&omci_ip_host_cfg_attr_data,
	sizeof(omci_ip_host_cfg_attr_data),
};

/*******************************************************************************************************************************
9.4.2: IP host performance monitoring history data

********************************************************************************************************************************/

omci_attr_dscp_t omci_attr_ip_host_pm_his_op[]={
{0, "meId",                     2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{1, "interval end time",        1,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{2, "threshold data 1/2 id",    2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,         ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{3, "icmp errors",              4,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{4, "dns errors",               4,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{5, "dhcp timeouts",            2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{6, "ip addr conflict",         2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{7, "out of memory",            2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{8, "internal error",           2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{255, "",                       0,  0,                              0,                          0,                      NULL}

};

int get_iphost_pm_history_data(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    if(syncFlag)
    {
        /*driver do not implement, so the value is 0*/
        pm_list->pm_data.iphost_pm.interEndTime = pmIntervalTimes;
    	pm_list->pm_data.iphost_pm.icmpErr = 0;
    	pm_list->pm_data.iphost_pm.dnsErr= 0;
    	pm_list->pm_data.iphost_pm.dhcpTimeouts= 0;
    	pm_list->pm_data.iphost_pm.ipAddrConfict= 0;
    	pm_list->pm_data.iphost_pm.outOfMem= 0;
    	pm_list->pm_data.iphost_pm.internalErr= 0;
    	
        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->icmpErr = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.iphost_pm.icmpErr);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dnsErr = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.iphost_pm.dnsErr);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dhcpTimeouts = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.iphost_pm.dhcpTimeouts);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->ipAddrConfict = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.iphost_pm.ipAddrConfict);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->outOfMem = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.iphost_pm.outOfMem);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->internalErr = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.iphost_pm.internalErr);
    }
        
    return 0;
}

int omci_me_iphost_pm_history_get_curr_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    omci_ip_host_pm_his_ptr iphost_pm_new = NULL;
    
    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    iphost_pm_new = (omci_ip_host_pm_his_ptr)me_info->attributes;
    if(iphost_pm_new == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]me info attribute is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    /*driver do not implement, so the value is 0*/

	iphost_pm_new->interEndTime= pmIntervalTimes;
	iphost_pm_new->icmpErr= 0;
	iphost_pm_new->dnsErr= 0;
	iphost_pm_new->dhcpTimeouts= 0;
	iphost_pm_new->ipAddrConfict= 0;
	iphost_pm_new->outOfMem= 0;
	iphost_pm_new->internalErr= 0;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->icmpErr = 0x%x\n",__FUNCTION__,__LINE__, iphost_pm_new->icmpErr);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dnsErr = 0x%x\n",__FUNCTION__,__LINE__, iphost_pm_new->dnsErr);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dhcpTimeouts = 0x%x\n",__FUNCTION__,__LINE__, iphost_pm_new->dhcpTimeouts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->ipAddrConfict = 0x%x\n",__FUNCTION__,__LINE__, iphost_pm_new->ipAddrConfict);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->outOfMem = 0x%x\n",__FUNCTION__,__LINE__, iphost_pm_new->outOfMem);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->internalErr = 0x%x\n",__FUNCTION__,__LINE__, iphost_pm_new->internalErr);
	

    return 0;
}


int omci_me_iphost_pm_history_notify(pm_history_data_list_ptr pm_list, omci_me_info_t threshold_info)
{
    enum{ IPHOST_PM_HISTORY_DATA_TCA_NUM = 6};
    omci_threshold_data_1_ptr threshold_data1 = NULL;
    int i = 0;
    uint32_t currentData[IPHOST_PM_HISTORY_DATA_TCA_NUM] = {0};
    static uint8_t reportFlag[IPHOST_PM_HISTORY_DATA_TCA_NUM] = {0};
    uint8_t alarm_num[IPHOST_PM_HISTORY_DATA_TCA_NUM] = {1, 2, 3, 4, 5, 6};
    tca_notify_info_t tca_info = {0};

    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(omci_pm_is_end_of_interval_time())
    {
        memset(reportFlag, 0, sizeof(reportFlag));
        return 0;
    }
    if(threshold_info.class_id != OMCI_CLASS_ID_THRESHOLD_DATA1){
        return 0;
    }

	threshold_data1 =  (omci_threshold_data_1_ptr)threshold_info.attributes;
    if(threshold_data1 == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  threshold value is NULL \n",__FUNCTION__,__LINE__);
        return -1;
    }

    for(i = 0; i < IPHOST_PM_HISTORY_DATA_TCA_NUM; i++)
    {
        tca_info.classId = pm_list->classId;
        tca_info.instId = pm_list->instId;
        tca_info.currentData = currentData[i];
        tca_info.threshold = threshold_data1->thresholdValue[i];
        tca_info.alarm_num = alarm_num[i];
        tca_info.reportFlag = reportFlag[i];

        reportFlag[i] = omci_pm_report_alarm_by_tca_info(tca_info, 0);
	}

	return 0;
    
}


omci_me_func_t omci_me_ip_host_pm_his_op ={
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_set_op,
	omci_me_general_pm_history_get_op,
	omci_me_iphost_pm_history_get_curr_op,
};

omci_ip_host_pm_his_t omci_ip_host_pm_his_attr_data = {0};

omci_attr_t omci_ip_host_pm_his_attr ={
	(uint8_t *)&omci_ip_host_pm_his_attr_data,
	sizeof(omci_ip_host_pm_his_attr_data),
};

/*******************************************************************************************************************************
9.4.3: TCP/UDP config data

********************************************************************************************************************************/
omci_attr_dscp_t omci_attr_tcp_udp_config_op[]={
{0, "meId",                     2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{1, "port id",                  2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{2, "protocol",                 1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{3, "tos or diffserv field",    1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{4, "ip host pointer",          2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,        ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{255, "",                       0,  0,                              0,                          0,                      NULL}

};

omci_me_func_t omci_me_tcp_udp_config_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_tcp_udp_cfg_t omci_tcp_udp_config_attr_data = {0};

omci_attr_t omci_tcp_udp_config_attr ={
	(uint8_t *)&omci_tcp_udp_config_attr_data,
	sizeof(omci_tcp_udp_config_attr_data),
};

/*******************************************************************************************************************************
9.4.4: TCP/UDP performance monitoring history data

********************************************************************************************************************************/

omci_attr_dscp_t omci_attr_tcp_udp_pm_his_op[]={
{0, "meId",                     2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,  ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{1, "interval end time",        1,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,  ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{2, "threshold data 1/2 id",    2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,       ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{3, "socket failed",            2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,  ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{4, "listen failed",            2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,  ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{5, "bind failed",              2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,  ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{6, "accept failed",            2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,  ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{7, "select failed",            2,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,  ATTR_FULLY_SUPPORT,		&generalAttrFunc},
{255, "", 						0, 	0,                              0,                          0,                  	NULL}
};


int get_tcp_udp_pm_history_data(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    if(syncFlag)
    {
        /*driver do not implement, so the value is 0*/
        pm_list->pm_data.tcp_udp_pm.interEndTime = pmIntervalTimes;
    	pm_list->pm_data.tcp_udp_pm.socketFailed = 0;
    	pm_list->pm_data.tcp_udp_pm.listenFailed = 0;
    	pm_list->pm_data.tcp_udp_pm.bindFailed = 0;
    	pm_list->pm_data.tcp_udp_pm.acceptFailed = 0;
    	pm_list->pm_data.tcp_udp_pm.selectFailed = 0;
    	
        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->socketFailed = 0x%x\n",__FUNCTION__,__LINE__,pm_list->pm_data.tcp_udp_pm.socketFailed);
        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->listenFailed = 0x%x\n",__FUNCTION__,__LINE__,pm_list->pm_data.tcp_udp_pm.listenFailed);
        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->bindFailed = 0x%x\n",__FUNCTION__,__LINE__,pm_list->pm_data.tcp_udp_pm.bindFailed);
        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->acceptFailed = 0x%x\n",__FUNCTION__,__LINE__,pm_list->pm_data.tcp_udp_pm.acceptFailed);
        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->selectFailed = 0x%x\n",__FUNCTION__,__LINE__,pm_list->pm_data.tcp_udp_pm.selectFailed);
    }
        
    return 0;
}

int omci_me_tcp_udp_pm_history_get_curr_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    omci_tcp_udp_pm_his_ptr tcp_udp_pm_new = NULL;
    
    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    tcp_udp_pm_new = (omci_tcp_udp_pm_his_ptr)me_info->attributes;
    if(tcp_udp_pm_new == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]me info attribute is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    /*driver do not implement, so the value is 0*/

	tcp_udp_pm_new->interEndTime = pmIntervalTimes;
	tcp_udp_pm_new->socketFailed = 0;
	tcp_udp_pm_new->listenFailed = 0;
	tcp_udp_pm_new->bindFailed = 0;
	tcp_udp_pm_new->acceptFailed = 0;
	tcp_udp_pm_new->selectFailed = 0;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->socketFailed = 0x%x\n",__FUNCTION__,__LINE__,tcp_udp_pm_new->socketFailed);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->listenFailed = 0x%x\n",__FUNCTION__,__LINE__,tcp_udp_pm_new->listenFailed);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->bindFailed = 0x%x\n",__FUNCTION__,__LINE__,tcp_udp_pm_new->bindFailed);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->acceptFailed = 0x%x\n",__FUNCTION__,__LINE__,tcp_udp_pm_new->acceptFailed);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->selectFailed = 0x%x\n",__FUNCTION__,__LINE__,tcp_udp_pm_new->selectFailed);
	

    return 0;
}


int omci_me_tcp_udp_pm_history_notify(pm_history_data_list_ptr pm_list, omci_me_info_t threshold_info)
{
    enum{ TCP_UDP_PM_HISTORY_DATA_TCA_NUM = 5};
    omci_threshold_data_1_ptr threshold_data1 = NULL;
    int i = 0;
    uint32_t currentData[TCP_UDP_PM_HISTORY_DATA_TCA_NUM] = {0};
    static uint8_t reportFlag[TCP_UDP_PM_HISTORY_DATA_TCA_NUM] = {0};
    uint8_t alarm_num[TCP_UDP_PM_HISTORY_DATA_TCA_NUM] = {0};
    tca_notify_info_t tca_info = {0};

    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(omci_pm_is_end_of_interval_time())
    {
        memset(reportFlag, 0, sizeof(reportFlag));
        return 0;
    }
    if(threshold_info.class_id != OMCI_CLASS_ID_THRESHOLD_DATA1){
        return 0;
    }

	threshold_data1 =  (omci_threshold_data_1_ptr)threshold_info.attributes;

    if(threshold_data1 == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  threshold value is NULL \n",__FUNCTION__,__LINE__);
        return -1;
    }

    for(i = 0; i < TCP_UDP_PM_HISTORY_DATA_TCA_NUM; i++)
    {
        tca_info.classId = pm_list->classId;
        tca_info.instId = pm_list->instId;
        tca_info.currentData = currentData[i];
        tca_info.threshold = threshold_data1->thresholdValue[i];
        tca_info.alarm_num = alarm_num[i];
        tca_info.reportFlag = reportFlag[i];

        reportFlag[i] = omci_pm_report_alarm_by_tca_info(tca_info, 0);
	}

	return 0;
    
}


omci_me_func_t omci_me_tcp_udp_pm_his_op ={
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_set_op,
	omci_me_general_pm_history_get_op,
	omci_me_tcp_udp_pm_history_get_curr_op,
};

omci_tcp_udp_pm_his_t omci_tcp_udp_pm_his_attr_data = {0};

omci_attr_t omci_tcp_udp_pm_his_attr ={
	(uint8_t *)&omci_tcp_udp_pm_his_attr_data,
	sizeof(omci_tcp_udp_pm_his_attr_data),
};


/*******************************************************************************************************************************
ME 250 PPPoE Wan config info 

********************************************************************************************************************************/

#define OMCI_PPPOE_CFG_ATTR_NAT_MODE		1
#define OMCI_PPPOE_CFG_ATTR_AUTH_VAL        2
#define OMCI_PPPOE_CFG_ATTR_CONNECT_MODE    3
#define OMCI_PPPOE_CFG_ATTR_RELEASE_TIME    4
#define OMCI_PPPOE_CFG_ATTR_USERNAME        5
#define OMCI_PPPOE_CFG_ATTR_PASSWORD        6
#define OMCI_PPPOE_CFG_ATTR_IPHOST_TP       9
#define OMCI_PPPOE_CFG_ATTR_USERNAME_STR_TP 10
#define OMCI_PPPOE_CFG_ATTR_LARGE_STR_TP    11

int setPPPoECfgAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr,int type)
{
    omci_PPPoE_wan_info_ptr config_info = NULL;
    
    if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }

    if (0 == omciPPPoEInfo.enable ){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"Suport for ME 250 is not enabled \n");
        return 0;
    }

    config_info = (omci_PPPoE_wan_info_ptr)me_info->attributes;

    switch (type)
    {
        case OMCI_PPPOE_CFG_ATTR_NAT_MODE:
            omciPPPoEInfo.NATMode = config_info->natMode;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: NAT mode = %d\n",omciPPPoEInfo.NATMode);
            break;
        case OMCI_PPPOE_CFG_ATTR_AUTH_VAL:
            omciPPPoEInfo.AuthVal= config_info->authValue;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: Auth value = %d\n",omciPPPoEInfo.AuthVal);
            break;
        case OMCI_PPPOE_CFG_ATTR_CONNECT_MODE:
            omciPPPoEInfo.connectMode= config_info->connectMode;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: Auth value = %d\n",omciPPPoEInfo.connectMode);
            break;
        case OMCI_PPPOE_CFG_ATTR_RELEASE_TIME:
            omciPPPoEInfo.releaseTime = config_info->releaseTime;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: release time = %d\n",omciPPPoEInfo.releaseTime);
            break;
        case OMCI_PPPOE_CFG_ATTR_IPHOST_TP:
            omciPPPoEInfo.iphostId = config_info->iphostTPPoint;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: iphostId = %d\n",omciPPPoEInfo.iphostId);
            break;
        case OMCI_PPPOE_CFG_ATTR_LARGE_STR_TP:
            omciPPPoEInfo.serviceStrTP = config_info->serviceNamePoint;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: large string pointer = %d\n",omciPPPoEInfo.serviceStrTP);
            break;
        case OMCI_PPPOE_CFG_ATTR_USERNAME:
            memcpy(omciPPPoEInfo.username, config_info->userName, strlen(config_info->userName));
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: username = %s\n",omciPPPoEInfo.username);
            break;
        case OMCI_PPPOE_CFG_ATTR_PASSWORD:
            memcpy(omciPPPoEInfo.password, config_info->password, strlen(config_info->password));
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: password = %s\n",omciPPPoEInfo.password);
            break;
        case OMCI_PPPOE_CFG_ATTR_USERNAME_STR_TP:
            omciPPPoEInfo.userNameStrTP = config_info->userNamePoint;
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPPPoECfgAttr: large string en = %d\n",omciPPPoEInfo.userNameStrTP);
            break;


        default :
            break;
    }
    return 0;
}

int setPPPoECfgNATModeAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_NAT_MODE);    
}

static attribute_func_t PPPoECfgNATModeGetSetFunc ={
    NULL,
    setPPPoECfgNATModeAttr
};

int setPPPoECfgAuthValAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_AUTH_VAL);    
}

static attribute_func_t PPPoECfgAuthValGetSetFunc ={
    NULL,
    setPPPoECfgAuthValAttr
};

int setPPPoECfgConnectModeAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_CONNECT_MODE);    
}

static attribute_func_t PPPoECfgConnectModeGetSetFunc ={
    NULL,
    setPPPoECfgConnectModeAttr
};

int setPPPoECfgRelTimeAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_RELEASE_TIME);    
}
static attribute_func_t PPPoECfgRelTimeGetSetFunc ={
    NULL,
    setPPPoECfgRelTimeAttr
};

int setPPPoECfgUserNameAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_USERNAME);    
}
static attribute_func_t PPPoECfgUserNameGetSetFunc ={
    NULL,
    setPPPoECfgUserNameAttr
};

int setPPPoECfgPasswordAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_PASSWORD);    
}
static attribute_func_t PPPoECfgPasswordGetSetFunc ={
    NULL,
    setPPPoECfgPasswordAttr
};


int setPPPoECfgIPHostTPAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_IPHOST_TP);    
}
static attribute_func_t PPPoECfgIPHotTPGetSetFunc ={
    NULL,
    setPPPoECfgIPHostTPAttr
};

int setPPPoECfgUserNameTPAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_USERNAME_STR_TP);    
}
static attribute_func_t PPPoECfgUserNameTPGetSetFunc ={
    NULL,
    setPPPoECfgUserNameTPAttr
};


int setPPPoECfgSrvNameTPAttr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    return setPPPoECfgAttr(me_info,omci_attr,OMCI_PPPOE_CFG_ATTR_LARGE_STR_TP);    
}
static attribute_func_t PPPoECfgSrvNameTPGetSetFunc ={
    NULL,
    setPPPoECfgSrvNameTPAttr
};

omci_attr_dscp_t omci_attr_PPPoE_wan_config_op[]=
{
{0, "meId" , 					      2 , ATTR_ACCESS_R_W_SET_CREATE,   ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "NAT mode" ,  		              1 , ATTR_ACCESS_R_W_SET_CREATE,   ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &PPPoECfgNATModeGetSetFunc},
{2, "Auth value" , 		              1 , ATTR_ACCESS_R_W,              ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &PPPoECfgAuthValGetSetFunc},
{3, "Connect mode" ,			      1 , ATTR_ACCESS_R_W,              ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &PPPoECfgConnectModeGetSetFunc},
{4, "Release Time" ,			      2 , ATTR_ACCESS_R_W,              ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &PPPoECfgRelTimeGetSetFunc},
{5, "Username" ,			          25 ,ATTR_ACCESS_R_W,              ATTR_FORMAT_STRING,	      ATTR_FULLY_SUPPORT, &PPPoECfgUserNameGetSetFunc},
{6, "Password" , 		              25 ,ATTR_ACCESS_R_W,              ATTR_FORMAT_STRING,	      ATTR_FULLY_SUPPORT, &PPPoECfgPasswordGetSetFunc},
{7, "attribute 7" , 		          1 , ATTR_ACCESS_R_W,              ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &generalAttrFunc},
{8, "attribute 8" ,			          1 , ATTR_ACCESS_R_W,              ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &generalAttrFunc},
{9, "IPHost TP pointer" ,			  2 , ATTR_ACCESS_R_W_SET_CREATE,   ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &PPPoECfgIPHotTPGetSetFunc},
{10, "Large string for Username" ,    2 , ATTR_ACCESS_R_W,              ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &PPPoECfgUserNameTPGetSetFunc},
{11, "Large string for service Name" ,2 , ATTR_ACCESS_R_W,              ATTR_FORMAT_UNSIGNED_INT, ATTR_FULLY_SUPPORT, &PPPoECfgSrvNameTPGetSetFunc},

{255, "",                             0,  0,               0,                           0,                  NULL}
};

omci_me_func_t omci_me_PPPoE_wan_config_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_PPPoE_wan_info_t omci_PPPoE_wan_cfg_attr_data = {0};

omci_attr_t omci_PPPoE_wan_cfg_attr_attr ={
	(uint8_t *)&omci_PPPoE_wan_cfg_attr_data,
	sizeof(omci_PPPoE_wan_cfg_attr_data),
};



/************************************************************************
*                  F U N C T I O N   D E F I N I T I O N S
*************************************************************************
*/



/*******************************************************************************************************************************
9.4.1: IP host config data

********************************************************************************************************************************/
void ipOption(IPHostConfig *ptr)
{	
	char cmd[256];

	ipOptionId[ptr->instId] = 0;

	if(ptr->ipOptions & IP_OPTION_ENABLE_PING_RESPONSE_MASK){/*ping response*/
		sprintf(cmd, "/usr/bin/iptables -D OUTPUT -p icmp --icmp-type 0 -o %s -j DROP", ptr->ifName);
		system(cmd);
	}
	else{//Static IP
		sprintf(cmd, "/usr/bin/iptables -D OUTPUT -p icmp --icmp-type 0 -o %s -j DROP", ptr->ifName);
		system(cmd);
		
		sprintf(cmd, "/usr/bin/iptables -A OUTPUT -p icmp --icmp-type 0 -o %s -j DROP", ptr->ifName);
		system(cmd);
	}

	if(ptr->ipOptions & IP_OPTION_ENABLE_TRACERT_RESPONSE_MASK){ /*trace route response*/
		sprintf(cmd, "/usr/bin/iptables -D OUTPUT -p icmp --icmp-type 11 -o %s -j DROP", ptr->ifName);
		system(cmd);
#if/*TCSUPPORT_COMPILE*/ !defined(TCSUPPORT_CMCC)		
		sprintf(cmd, "/usr/bin/iptables -D INPUT -p udp --dport 32768: -i %s -j DROP", ptr->ifName);
		system(cmd);
#endif/*TCSUPPORT_COMPILE*/
	}
	else{/*Static IP*/
		sprintf(cmd, "/usr/bin/iptables -D OUTPUT -p icmp --icmp-type 11 -o %s -j DROP", ptr->ifName);
		system(cmd);
		
		sprintf(cmd, "/usr/bin/iptables -A OUTPUT -p icmp --icmp-type 11 -o %s -j DROP", ptr->ifName);
		system(cmd);
#if/*TCSUPPORT_COMPILE*/ !defined(TCSUPPORT_CMCC)
		sprintf(cmd, "/usr/bin/iptables -D INPUT -p udp --dport 32768: -i %s -j DROP", ptr->ifName);
		system(cmd);
	
		sprintf(cmd, "/usr/bin/iptables -A INPUT -p udp --dport 32768: -i %s -j DROP", ptr->ifName);
		system(cmd);
#endif/*TCSUPPORT_COMPILE*/
	}
}

int get_profile_str(char *keyname,char *str_return, int size, int type, char *path)
{

	FILE *fp = NULL;
	char *str_key = NULL;
	char stream[128] = {0};
	int enterOffSet = 1;
	int qmarkLength = 0;
	int skipQmark = 0;
	int totalLength = 0;

	fp = fopen(path,"r");
	if(fp == NULL){
		fprintf(stderr,"Can't open %s\n",path);
		return -1;
	}

	memset(str_return, 0, size);
	fseek(fp, 0, 0);
	if(type == 1){
		qmarkLength = 2;
		skipQmark = 1;
	}
	else if(type == 0){
		qmarkLength = 0;
		skipQmark = 0;
	}
	else{
		fprintf(stderr, "The input qmark type of get_profile_str is wrong \n");
		fclose(fp);
		return -1;
	}

	while(fgets(stream, 128, fp) != NULL){
		//str_enter = strrchr(stream,'\n');
		if(strrchr(stream,'\n') == NULL){
			enterOffSet = 0;
		}
		else{
			enterOffSet = 1;
		}

		str_key = strstr(stream,keyname);
		if(str_key == NULL || str_key != stream){
			continue;
		}

		totalLength = strlen(stream) - strlen(keyname) - enterOffSet - qmarkLength;
		if(size < totalLength+1){/*total length + '\0' should not less than buffer*/
			fprintf(stderr, "Too small buffer to catch the %s frome get_profile_str\n", keyname);
			fclose(fp);
			return -1;
		}
		else if(totalLength < 0) {/*can't get a negative length string*/
			fprintf(stderr, "No profile string can get\n");
			fclose(fp);
			return -1;
		}
		else{
			strncpy(str_return, stream+strlen(keyname)+skipQmark, totalLength);
			str_return[totalLength] = '\0';
			fclose(fp);
			return strlen(str_return);
		}
	}
	fclose(fp);
	fprintf(stderr,"File %s content %s is worng\n",path,keyname);
	
	return -1;
}


int checkSubnetLegal(char *mask)
{	
	uint32_t netmask = 0, broadcast = 0;
	int i = 0;

	if(mask == NULL)
		return 0;

	netmask = aton(mask);
	broadcast = aton("255.255.255.255");

	for(i = 0; i < 32; i++) {
		if(netmask & (1 << i))
			break;
		broadcast &= ~(1 << i);
	}

	if(broadcast != netmask) {
		return 0;
	}

	return 1;
}

int checkInternalClientIp(char *st)
{
	int i = 0, dot = 0;
	int i1 =0 ,i2 = 0 ,i3 = 0, i4 = 0;
	int len = 0;

	if(strcmp(st, "0.0.0.0") == 0)
		return 1;

	len = strlen(st);
	if(len < 7 || len > 15)
		return 0;
	
	for(i = 0; i<len; i++)
	{
		if(((*(st+i)) <= '9')&&((*(st+i)) >= '0'))
		{
			if(dot == 0){
				i1 = i1 *10 + (*(st+i)-'0');
			}
			else if(dot ==1) {
				i2 = i2 *10 + (*(st+i)-'0');
			}
			else if(dot ==2) {
				i3 = i3 *10 + (*(st+i)-'0');
			}		
			else if(dot ==3) {
				i4 = i4 *10 + (*(st+i)-'0');
			}
		}
		else if((*(st+i)) == '.')
			dot++;
		else if((*(st+i)) > '9')//error
			return 0;
		else if((*(st+i)) < '0')//error
			return 0;
	}
	
	//printf("i = %d, dot = %d, i1(%d), i2(%d), i3(%d), i4(%d)\n",i, dot, i1,i2,i3,i4);
	if (dot != 3)
		return 0;

	if(i1 == 0 || i4 == 255 || i1 == 127 )	
		return 0;

	if ((i1>223) || (i2>255) || (i3>255) || (i4>255))
		return 0;

	return 1;
}

static void omciPreSetIPhostIstId(uint16_t * istId)
{
    if(isFiberhome_551601){
        *istId += 0x1;
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] isFiberhome_551601,istId=%d.\n",__FUNCTION__,__LINE__,*istId);
    }
}

int getIPHostWanInterfaceType(uint16_t instanceId)
{
    uint16_t istId = 0;
    int i = 0;
    int j = 0;
	uint16_t tcp_udp_inst_id_array[MAX_INST_COUNT]={0};
	int tcp_udp_inst_count = 0;
	omci_me_info_t tcp_udp_me_info = {0};
	omci_tcp_udp_cfg_ptr  tcp_udp_cfg_ptr = NULL;
	uint16_t veip_inst_id_array[MAX_INST_COUNT]={0};
	uint16_t sip_agent_inst_id_array[MAX_INST_COUNT]={0};
	int veip_inst_count = 0;
	int sip_agent_inst_count = 0;
	omci_me_info_t veip_me_info = {0};
	omci_veip_ptr veip_attr = NULL;
	omci_sip_agent_cfg_ptr sip_agent_ptr = NULL;
	omci_me_info_t tr069_me_info = {0};
	omci_me_info_t sip_me_info = {0};
	omci_me_info_t curMeInfo = {0};
    
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
	return WAN_SERVICELIST_VOICE;
#endif/*TCSUPPORT_COMPILE*/

    if(omciWanType[instanceId] != WAN_SERVICELIST_MAX)
    {
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d] return service type %d\n",__FUNCTION__,__LINE__,omciWanType[instanceId]);
        return omciWanType[instanceId];
    }

    istId = instanceId;
    omciPreSetIPhostIstId(&istId);

    /*1. ip_host <------- TCP/UDP config data <------ VEIP ----- TR069 management */

	tcp_udp_me_info.class_id = OMCI_CLASS_ID_TCP_UDP_CFGDATA;
	if(omci_lib_get_inst_count_by_classid(tcp_udp_me_info.class_id, &tcp_udp_inst_count) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_lib_get_inst_count_by_classid failed.\n",__FUNCTION__,__LINE__);
		return -1;
	}
	
	if(omci_lib_get_inst_list_by_classid(tcp_udp_me_info.class_id, tcp_udp_inst_id_array, tcp_udp_inst_count) == -1){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_lib_get_inst_list_by_classid failed.\n",__FUNCTION__,__LINE__);
		return -1;
	}


	for(i = 0; i < tcp_udp_inst_count; i++){
		/*3.1 get 9.3.4 instance id*/
		tcp_udp_me_info.inst_id = tcp_udp_inst_id_array[i];
		if(omci_attr_get_all_data_except_table_attr(&tcp_udp_me_info) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get data failed.\n",__FUNCTION__,__LINE__);
			continue;
		}
		
		tcp_udp_cfg_ptr = (omci_tcp_udp_cfg_ptr)tcp_udp_me_info.attributes;
		if(NULL == tcp_udp_cfg_ptr){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "%s->tcp_udp_cfg_attr calloc fail\n",__FUNCTION__);
			continue;
		}

		if(tcp_udp_cfg_ptr->ipHostPointer != istId){
		    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]TCP/UDP's iphost pointer is not exist.\n",__FUNCTION__,__LINE__);
			continue;
		}

        /* get VEIP which is point to this TCP/UDP config data*/
		veip_me_info.class_id = OMCI_CLASS_ID_VIRTUAL_ETHERNET_INTERFACE_POINT;
		if(omci_lib_get_inst_count_by_classid(veip_me_info.class_id, &veip_inst_count) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_lib_get_inst_count_by_classid failed.\n",__FUNCTION__,__LINE__);
			return -1;
		}
		
		if(omci_lib_get_inst_list_by_classid(veip_me_info.class_id, veip_inst_id_array, veip_inst_count) == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_lib_get_inst_list_by_classid failed.\n",__FUNCTION__,__LINE__);
			return -1;
		}
		
		for(j = 0; j < veip_inst_count; j++){
			veip_me_info.inst_id = veip_inst_id_array[j];
			if(omci_attr_get_all_data_except_table_attr(&veip_me_info) != 0){
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get data failed.\n",__FUNCTION__,__LINE__);
				continue;
			}
			
			veip_attr = (omci_veip_ptr)veip_me_info.attributes;
			if(NULL == veip_attr){
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "%s->veip_attr calloc fail\n",__FUNCTION__);
				continue;
			}
			if(veip_attr->tcpUdpPointer != tcp_udp_me_info.inst_id){
			    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]VEIP's TCP/UDP Pointer is not exist.\n",__FUNCTION__,__LINE__);
				continue;
			}

			/* get TR069 management by instance id */
			tr069_me_info.class_id = OMCI_CLASS_ID_TR069_MANAGE_SERVER;
			tr069_me_info.inst_id = veip_me_info.inst_id;
			if(omci_attr_get_all_data_except_table_attr(&tr069_me_info) == 0){
				omciWanType[instanceId] = WAN_SERVICELIST_TR069;
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s %d return service type TR069\n",__FUNCTION__,__LINE__);
				return WAN_SERVICELIST_TR069;
			}			
		}
	}

	for(i = 0; i < tcp_udp_inst_count; i++)
	{
		/*3.1 get 9.3.4 instance id*/
		tcp_udp_me_info.inst_id = tcp_udp_inst_id_array[i];
		if(omci_attr_get_all_data_except_table_attr(&tcp_udp_me_info) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get data failed.\n",__FUNCTION__,__LINE__);
			continue;
		}
		
		tcp_udp_cfg_ptr = (omci_tcp_udp_cfg_ptr)tcp_udp_me_info.attributes;
		if(NULL == tcp_udp_cfg_ptr){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "%s->tcp_udp_cfg_attr calloc fail\n",__FUNCTION__);
			continue;
		}

		if(tcp_udp_cfg_ptr->ipHostPointer != istId){
		    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]TCP/UDP's iphost pointer is not exist.\n",__FUNCTION__,__LINE__);
			continue;
		}

		//check the current sip agent config data First, in case this inst hasn't add the meInstList yet.
		curMeInfo = getCurrentMeInfo();
		if(curMeInfo.class_id == OMCI_CLASS_ID_SIP_AGENT_CONFIG_DATA ){
			sip_agent_ptr = (omci_sip_agent_cfg_ptr)curMeInfo.attributes;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"%s %d  tcp_udp_id=%d,sip->tcpUdpPtr=%d\n",
			             __FUNCTION__,__LINE__,tcp_udp_me_info.inst_id,sip_agent_ptr->tcpOrUdpPtr);
			if(sip_agent_ptr->tcpOrUdpPtr == tcp_udp_me_info.inst_id){
				omciWanType[instanceId] = WAN_SERVICELIST_VOICE;
				omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"%s %d return service type VOICE\n",__FUNCTION__,__LINE__);
				return WAN_SERVICELIST_VOICE;
			}
		}
		
        /* get SIP agent config data which is point to this TCP/UDP config data*/
		sip_me_info.class_id = OMCI_CLASS_ID_SIP_AGENT_CONFIG_DATA;
		if(omci_lib_get_inst_count_by_classid(sip_me_info.class_id, &sip_agent_inst_count) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_lib_get_inst_count_by_classid failed.\n",__FUNCTION__,__LINE__);
			return -1;
		}
		
		if(omci_lib_get_inst_list_by_classid(sip_me_info.class_id, sip_agent_inst_id_array, sip_agent_inst_count) == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_lib_get_inst_list_by_classid failed.\n",__FUNCTION__,__LINE__);
			return -1;
		}

		for(i=0; i<sip_agent_inst_count; i++ ){
			sip_me_info.class_id = OMCI_CLASS_ID_SIP_AGENT_CONFIG_DATA;
			sip_me_info.inst_id = sip_agent_inst_id_array[i];
			if(omci_attr_get_all_data_except_table_attr(&sip_me_info) != 0){
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_lib_get_inst_count_by_classid failed.\n",__FUNCTION__,__LINE__);
				return -1;
			}
			
			sip_agent_ptr = (omci_sip_agent_cfg_ptr)sip_me_info.attributes;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"%s %d  tcp_udp_id=%d,sip->tcpUdpPtr=%d\n",
				__FUNCTION__,__LINE__,tcp_udp_me_info.inst_id,sip_agent_ptr->tcpOrUdpPtr);
			if(sip_agent_ptr->tcpOrUdpPtr == tcp_udp_me_info.inst_id){
				omciWanType[instanceId] = WAN_SERVICELIST_VOICE;
				omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"%s %d return service type VOICE\n",__FUNCTION__,__LINE__);
				return WAN_SERVICELIST_VOICE;
			}
		}
	}

/* not found !! for HW olt do not create  TCP/UDP config data for VEIP 0*/
#if defined(TCSUPPORT_PON_IP_HOST)
    istId = (0 == instanceId) ? 1 : 0;
    if (omciWanType[istId] == WAN_SERVICELIST_TR069)
    {
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s %d return service type VOICE\n",__FUNCTION__,__LINE__);
        return WAN_SERVICELIST_VOICE;
    }
    if (omciWanType[istId] == WAN_SERVICELIST_VOICE)
    {
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s %d return service type TR069\n",__FUNCTION__,__LINE__);        
        return WAN_SERVICELIST_TR069;
	}
        
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"%s %d return service type WAN_SERVICELIST_MAX\n",__FUNCTION__,__LINE__);
    return WAN_SERVICELIST_MAX;   //default tr69 wan
    
#endif
    return -1;
}

int omci_wan_convert_to_attr(int type, char* buf, char* attr)
{
	if((buf == NULL)||(attr == NULL))
    {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s input pointer buf is NULL return \n",__FUNCTION__);
	    return -1;
    }
	if(strlen(buf) <= MAX_WAN_ATTR_LENTH - 1)
	{
		switch(type)
		{
			case WAN_IF_TYPE_IP_ADDR:
		    case WAN_IF_TYPE_NETMASK:
		    case WAN_IF_TYPE_GATEWAY:
		    case WAN_IF_TYPE_PRI_DNS:
		    case WAN_IF_TYPE_SEC_DNS:
		        strcpy(attr,buf);
		        break;
		    default :
		        strcpy(attr,buf);
		        break;
		}
		return 0;
	}else{		
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s input pointer buf longer than max attr lenth \n",__FUNCTION__);		
		return -1;	
	}
		
}

static int omci_wan_record_info(uint16_t id,uint8_t type,char* val)	
{
	if(val == NULL)
    {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s input pointer buf is NULL return \n",__FUNCTION__);
	    return -1;
    }
	
    if(0 == g_iphost_wan[id].change)
    {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s] [%d] set iphost[%d] change to 1  \n",__FUNCTION__,__LINE__,id);
	    g_iphost_wan[id].change = 1;
    }

	if(type == WAN_IF_TYPE_SVC_LIST && (0 == omciPPPoEInfo.enable))
    {
        omci_link_to_web(id,val);
    }
    g_iphost_wan[id].attr_mask |= (1<<type);
    strncpy(g_iphost_wan[id].val[type],val,MAX_WAN_ATTR_LENTH-1);

	return 0;
}

void omci_link_to_web(uint16_t IPHostIstId,char* srvlist)
{
    int wan_idx = 0;
    int another_web_idx = 0;

    if(0 == memcmp(srvlist,WAN_SRV_TR069_STR,strlen(WAN_SRV_TR069_STR))){
        wan_idx = E_WAN_SVC_TYPE_TR069;
        another_web_idx = E_WAN_SVC_TYPE_VOICE;
    }
    else{
        wan_idx = E_WAN_SVC_TYPE_VOICE;
        another_web_idx = E_WAN_SVC_TYPE_TR069;
    }
    g_web_rcd_info[wan_idx].change = 1;
    g_web_rcd_info[wan_idx].iphostId = IPHostIstId;
    if(IPHostIstId == g_web_rcd_info[another_web_idx].iphostId)
    {
        g_web_rcd_info[another_web_idx].iphostId = MAX_IPHOST_WAN_NUM;
    }
    /* srv list change clear path info */
    if (0 != memcmp(g_iphost_wan[IPHostIstId].val[WAN_IF_TYPE_SVC_LIST],srvlist,strlen(srvlist)) 
            && 0 != strlen(g_iphost_wan[IPHostIstId].path)){
        memset(g_iphost_wan[IPHostIstId].path,0,MAX_WAN_PATH_LENTH);
    }
    return;

}

uint8_t svclist_is_tr69(uint16_t IPHostId)
{
    char * srvlist = g_iphost_wan[IPHostId].val[WAN_IF_TYPE_SVC_LIST];
    if(0 == memcmp(srvlist,WAN_SRV_TR069_STR,strlen(WAN_SRV_TR069_STR))){
        return 1;
    }
    else{
        return 0;
    }
}

void omci_wan_clear_change(uint16_t IPHostIstId)
{    
	g_iphost_wan[IPHostIstId].change = 0;
    g_iphost_wan[IPHostIstId].attr_mask = 0;
    memset(g_iphost_wan[IPHostIstId].val[WAN_IF_TYPE_SVC_LIST],0, MAX_WAN_ATTR_LENTH);
}


static int omci_wan_check_change(uint16_t IPHostIstId)
{    
	
	    /*OLT only set ISP and ISP is set to 0, and ip address  0*/
    if((0 != ((1<<WAN_IF_TYPE_ISP) & g_iphost_wan[IPHostIstId].attr_mask)) 
        && (0 == strcmp(g_iphost_wan[IPHostIstId].val[WAN_IF_TYPE_ISP],"1"))
        && (0 != ((1<<WAN_IF_TYPE_IP_ADDR) & g_iphost_wan[IPHostIstId].attr_mask))
        && (0 == strcmp(g_iphost_wan[IPHostIstId].val[WAN_IF_TYPE_IP_ADDR],"0.0.0.0")))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] static ip host but ip address set 0 fail return.\n", __FUNCTION__, __LINE__);
        return 0;
    }
   else  if((0 != ((1<<WAN_IF_TYPE_ISP) & g_iphost_wan[IPHostIstId].attr_mask))
        && (0 == strcmp(g_iphost_wan[IPHostIstId].val[WAN_IF_TYPE_ISP],"1"))
        && (0 == ((1<<WAN_IF_TYPE_IP_ADDR) & g_iphost_wan[IPHostIstId].attr_mask)))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] static ip host but do not set ip address return.\n", __FUNCTION__, __LINE__);
        return 0;
    }
   else
   {
	//nothing
   }
    
	return g_iphost_wan[IPHostIstId].change;
}

int setWanInfo(int type ,uint16_t IPHostIstId, char* buf)
{
    char attr_val[MAX_WAN_ATTR_LENTH-1] 	= {0};
	/* this function just record wan info, set and commit will delay to monitor done */
    if(omci_wan_convert_to_attr(type,buf,attr_val) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"OMCI omci_wan_convert_to_attr fail return \n");
	    return -1;	    	
    }	
    if(omci_wan_record_info(IPHostIstId,type,attr_val) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"OMCI omci_wan_record_info fail return \n");
	    return -1;	    	
    }

	if (type == WAN_IF_TYPE_VLANID) {
		set_wan_vlan_id(IPHostIstId, buf);
		// timerStopS(commitWanTimer); 
		// commitWanTimer = timerStartS(5000 , (TimerCallback)omciFinishSetWanInfo, NULL);
	}

	if (type == WAN_IF_TYPE_DOT1P) {
		set_wan_priority(IPHostIstId, buf);
		// timerStopS(commitWanTimer); 
		// commitWanTimer = timerStartS(5000 , (TimerCallback)omciFinishSetWanInfo, NULL);
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"Enter [%s][%d] omci_info_g.trafficStatus %d type %d buf %s \n",
		__FUNCTION__,__LINE__,omci_info_g.trafficStatus, type, buf);

	if(1 == omci_info_g.trafficStatus){
		timerStopS(commitWanTimer); 
		commitWanTimer = timerStartS(5000 , (TimerCallback)omciFinishSetWanInfo, NULL);
	}

    return 0;
}

static void omci_check_srvlist(void)
{
    uint16_t valid[MAX_IPHOST_WAN_NUM] = 
                {   g_iphost_wan[0].attr_mask & (1<<WAN_IF_TYPE_SVC_LIST),
                    g_iphost_wan[1].attr_mask & (1<<WAN_IF_TYPE_SVC_LIST)};

    uint16_t check_idx = 0;
    uint16_t another_idx = 0;
    for(check_idx = 0; check_idx < MAX_IPHOST_WAN_NUM; check_idx ++)
    {
        if(0 != valid[check_idx]){
            continue;
        }
        g_iphost_wan[check_idx].attr_mask |= (1<<WAN_IF_TYPE_SVC_LIST);
        another_idx = (0 == check_idx) ? 1 : 0;
        if(0 != valid[another_idx])
        {
            if(svclist_is_tr69(another_idx))
            {
                strcpy(g_iphost_wan[check_idx].val[WAN_IF_TYPE_SVC_LIST],WAN_SRV_VOICE_SRV);
            }
            else
            {
                strcpy(g_iphost_wan[check_idx].val[WAN_IF_TYPE_SVC_LIST],WAN_SRV_TR069_STR);
            }
            break;
        }
        /*if srvlist not set default is tr069 type*/
        strcpy(g_iphost_wan[check_idx].val[WAN_IF_TYPE_SVC_LIST],WAN_SRV_TR069_STR);
    }
    return;
}

int omciFinishSetWanInfo(void)
{
	uint16_t iphostId = 0;

	commitWanTimer = 0; 
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s] [%d] start to config IPHOST wan info \n",__FUNCTION__,__LINE__);
    omci_wan_dump_web_rcd();
    omci_wan_dump_iphost_wan();

    /* wan config change after traffic is up, old config should be recovery */
    if(LINK_UP == omci_info_g.trafficStatus  && !omciPPPoEInfo.enable)
    {
        omci_wan_recovery_web(E_WAN_SVC_TYPE_MAX);
        omci_wan_clear_all();
    }
    omci_check_srvlist();
	for(iphostId = 0;iphostId < MAX_IPHOST_WAN_NUM;iphostId++)
    {
        if(omci_wan_check_change(iphostId) != 1)
    	{
    		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"[%s][%d] wan attr not chage, iphostId = %d\n",__FUNCTION__,__LINE__, iphostId);
            omci_wan_clear_change(iphostId);
    		continue;
    	}
        omci_wan_set_effect(iphostId);
    }

    return 0;
}



int setIPHostConfigDataIPOptions(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
    char isp[OMCI_LAYER3_VAL_BUFF_SIZE] = {0};
    omci_ip_host_cfg_ptr new_iphost = NULL;
    char linkMode[OMCI_LAYER3_VAL_BUFF_SIZE] = {0};

    if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }

    if(me_info->inst_id >= MAX_IPHOST_WAN_NUM)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info inst_id[%d] is wrong\n", __FUNCTION__, __LINE__, me_info->inst_id);
        return -1;
    }
    memset(&configData[me_info->inst_id],0,sizeof(IPHostConfig));
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;

    configData[me_info->inst_id].instId = me_info->inst_id;
    configData[me_info->inst_id].ipOptions = new_iphost->ipOptions;
    if(configData[me_info->inst_id].ipOptions & IP_OPTION_DHCP_MASK){ /*DHCP*/
        strcpy(isp, "0");
    }
    else {/*Static IP*/
        strcpy(isp, "1");
    }
    setWanInfo(WAN_IF_TYPE_ISP, me_info->inst_id,isp);
	
	//overwrite linkMode as "linkIP", othwise if linkMode was set as "linkPPP" by web and omci reuse this wan,will cause get ip fail
	strcpy(linkMode, "linkIP");
	setWanInfo(WAN_IF_TYPE_LINKMODE, me_info->inst_id,linkMode);
	
    if (ipOptionId[me_info->inst_id] > 0){
        timerStopS(ipOptionId[me_info->inst_id]);
        ipOptionId[me_info->inst_id] = 0;
    }
    ipOptionId[me_info->inst_id] = timerStartS(1*TIMER_COUNT_S,(TimerCallback)ipOption, &configData[me_info->inst_id]);
    if (ipOptionId[me_info->inst_id] < 0){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] timerStartS fail!.\n", __FUNCTION__, __LINE__);
        return -1;
    }

    return 0;

}

int getIPHostConfigDataMACAddr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	int mac[8] = {0};
	char tmpMAC[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	int i = 0;
	omci_ip_host_cfg_ptr new_iphost = NULL;

	if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }

    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;
#ifndef BSP_BUILD	
#ifdef TCSUPPORT_PON_IP_HOST
    if(omci_wan_get_attr(WAN_IF_TYPE_MAC_ADDR, me_info->inst_id, tmpMAC,sizeof(tmpMAC)) == 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] get wanInfo mac success\n", __FUNCTION__, __LINE__);
    }
    else
    {
        if(get_profile_str("LAN_MAC=", tmpMAC, sizeof(tmpMAC), 0, IP_HOST_MAC_PATH) == -1)
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo mac FAIL\n", __FUNCTION__, __LINE__);
            return -1;
        }
    }
#else
	if(get_profile_str("LAN_MAC=", tmpMAC, sizeof(tmpMAC), 0, IP_HOST_MAC_PATH) == -1)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo mac FAIL\n", __FUNCTION__, __LINE__);
		return -1;
    }
#endif
#else
	if(gponmgr_lib_get_dev_mac((unsigned char *)tmpMAC) != 0)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo mac FAIL\n", __FUNCTION__, __LINE__);
		return -1;
    }
#endif					
	sscanf(tmpMAC, "%02x:%02x:%02x:%02x:%02x:%02x", &mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5]);
	memset(tmpMAC, 0, sizeof(tmpMAC));
	for(i=0; i<6; i++)
	{
		new_iphost->macAddr[i]= (uint8_t)mac[i];
	}

    return 0;
}

int setIPHostConfigDataIPAddr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	char ipAddr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;
	omci_ip_host_cfg_ptr new_iphost = NULL;

	if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }

    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;

	memset(&address, 0, sizeof(address));
	address.s_addr = htonl(new_iphost->ipAddress);
	strncpy(ipAddr, (char *)inet_ntoa(address),OMCI_LAYER3_STR_BUFF_SIZE-1);
	if(checkInternalClientIp(ipAddr) == 0)
	{
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] check valid error\n", __FUNCTION__, __LINE__);
        return -1;
    }

#ifdef TCSUPPORT_PON_IP_HOST
	setWanInfo(WAN_IF_TYPE_IP_ADDR, me_info->inst_id,ipAddr);
#else
	//tcapi_set("Lan_Entry0", "IP", ipAddr);
	//tcapi_commit("Lan_Entry0");
	//tcapi_save();
#endif
	
	return 0;
}

int setIPHostConfigDataMask(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	char mask[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;

	omci_ip_host_cfg_ptr new_iphost = NULL;

	if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }

    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;


	memset(&address, 0, sizeof(address));
	address.s_addr = htonl(new_iphost->mask);
	strncpy(mask, (char *)inet_ntoa(address),OMCI_LAYER3_STR_BUFF_SIZE-1);
	if(checkSubnetLegal(mask) == 0)
	{
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] check valid error\n", __FUNCTION__, __LINE__);
        return -1;
    }

#ifdef TCSUPPORT_PON_IP_HOST
	setWanInfo(WAN_IF_TYPE_NETMASK,me_info->inst_id,mask);
#else
	//tcapi_set("Lan_Entry0", "netmask", mask);
	//tcapi_commit("Lan_Entry0");
	//tcapi_save();
#endif
	
	return 0;
}


int setIPHostConfigDataGateway(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	char addr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;
	
    omci_ip_host_cfg_ptr new_iphost = NULL;
    
    if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;
	
	memset(&address, 0, sizeof(address));
	address.s_addr = htonl(new_iphost->gateway);
	strncpy(addr, (char *)inet_ntoa(address),OMCI_LAYER3_STR_BUFF_SIZE-1);
	if(checkInternalClientIp(addr) == 0)
	{
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] check valid error\n", __FUNCTION__, __LINE__);
        return -1;
    }
	
#ifdef TCSUPPORT_PON_IP_HOST
	setWanInfo(WAN_IF_TYPE_GATEWAY, me_info->inst_id,addr);
#endif
	
	return 0;
}

int setIPHostConfigDataPrimaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	char addr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;
	
    omci_ip_host_cfg_ptr new_iphost = NULL;
    
    if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;

	memset(&address, 0, sizeof(address));
	address.s_addr = htonl(new_iphost->primaryDNS);
	strncpy(addr, (char *)inet_ntoa(address),OMCI_LAYER3_STR_BUFF_SIZE-1);
	if(checkInternalClientIp(addr) == 0)
	{
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] check valid error\n", __FUNCTION__, __LINE__);
        return -1;
    }
	
#ifdef TCSUPPORT_PON_IP_HOST
	setWanInfo(WAN_IF_TYPE_PRI_DNS, me_info->inst_id,addr);
#endif

	
	return 0;
}

int setIPHostConfigDataSecondaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	char addr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;

	omci_ip_host_cfg_ptr new_iphost = NULL;
    
    if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;
    
	memset(&address, 0, sizeof(address));
	address.s_addr = htonl(new_iphost->secondaryDNS);
	strncpy(addr, (char *)inet_ntoa(address),OMCI_LAYER3_STR_BUFF_SIZE-1);
	if(checkInternalClientIp(addr) == 0)
	{
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] check valid error\n", __FUNCTION__, __LINE__);
        return -1;
    }
	
#ifdef TCSUPPORT_PON_IP_HOST
	setWanInfo(WAN_IF_TYPE_SEC_DNS, me_info->inst_id,addr);
#endif
	
	return 0;
}

int getIPHostConfigDataCurAddr(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{    
#ifdef TCSUPPORT_PON_IP_HOST
	char ipAddr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;
#endif
    omci_ip_host_cfg_ptr new_iphost = NULL;

    if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;

	if((new_iphost->ipOptions&IP_OPTION_DHCP_MASK) == 0)//DHCP disable, curAddr == addr
	{
		new_iphost->currentAddress = new_iphost->ipAddress;
	}
	else//DHCP enable, curAddr is assigned by DHCP, if not,  undefined
	{
#ifdef TCSUPPORT_PON_IP_HOST
		if(omci_wan_get_attr(WAN_IF_TYPE_IP_ADDR,me_info->inst_id,ipAddr,sizeof(ipAddr)) != 0){
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo curAddr fail\n", __FUNCTION__, __LINE__);
			return -1;
		}
        
		memset(&address, 0, sizeof(address));
		inet_aton(ipAddr, &address);

		new_iphost->currentAddress = ntohl(address.s_addr);		
#endif

	}
	
	return 0;
}

int getIPHostConfigDataCurMask(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
#ifdef TCSUPPORT_PON_IP_HOST
	char ipAddr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;
#endif

    omci_ip_host_cfg_ptr new_iphost = NULL;
	if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;
	

	if((new_iphost->ipOptions & IP_OPTION_DHCP_MASK) == 0)//DHCP disable, curAddr == addr
	{
		new_iphost->currentMask = new_iphost->mask;
	}
	else//DHCP enable, curAddr is assigned by DHCP, if not,  undefined
	{
#ifdef TCSUPPORT_PON_IP_HOST
		if(omci_wan_get_attr(WAN_IF_TYPE_NETMASK,me_info->inst_id,ipAddr,sizeof(ipAddr)) != 0){
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo curMask fail\n", __FUNCTION__, __LINE__);
			return -1;
		}

		memset(&address, 0, sizeof(address));
		inet_aton(ipAddr, &address);
		new_iphost->currentMask = ntohl(address.s_addr);
#endif
	}
	
	return 0;
}

int getIPHostConfigDataCurGateway(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
#ifdef TCSUPPORT_PON_IP_HOST
	char ipAddr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;
#endif 

	omci_ip_host_cfg_ptr new_iphost = NULL;
	if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;
	

	if((new_iphost->ipOptions & IP_OPTION_DHCP_MASK) == 0)//DHCP disable, curAddr == addr
	{
		new_iphost->currentGateway= new_iphost->gateway;
	}
	else//DHCP enable, curAddr is assigned by DHCP, if not,  undefined
	{
#ifdef TCSUPPORT_PON_IP_HOST
		if(omci_wan_get_attr(WAN_IF_TYPE_GATEWAY,me_info->inst_id,ipAddr,sizeof(ipAddr)) != 0){
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo curGateway fail\n", __FUNCTION__, __LINE__);
			return -1;
		}		

		memset(&address, 0, sizeof(address));
		inet_aton(ipAddr, &address);
			
		new_iphost->currentGateway= ntohl(address.s_addr);
#endif
	}
	
	return 0;
}

int getIPHostConfigDataCurPrimaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
#ifdef TCSUPPORT_PON_IP_HOST
	char ipAddr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
	struct in_addr address;
#endif

	omci_ip_host_cfg_ptr new_iphost = NULL;
	if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;
	

	if((new_iphost->ipOptions & IP_OPTION_DHCP_MASK) == 0)//DHCP disable, curAddr == addr
	{
		new_iphost->currentPrimaryDNS = new_iphost->primaryDNS;
	}
	else//DHCP enable, curAddr is assigned by DHCP, if not,  undefined
	{
#ifdef TCSUPPORT_PON_IP_HOST
		if(omci_wan_get_attr(WAN_IF_TYPE_PRI_DNS,me_info->inst_id,ipAddr,sizeof(ipAddr)) != 0){
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo curPrimaryDNS fail\n", __FUNCTION__, __LINE__);
			return -1;
		}		
        memset(&address, 0, sizeof(address));
		inet_aton(ipAddr, &address);

        new_iphost->currentPrimaryDNS = ntohl(address.s_addr);

#endif
	}
	
	return 0;
}

int getIPHostConfigDataCurSecondaryDNS(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
#ifdef TCSUPPORT_PON_IP_HOST
	char ipAddr[OMCI_LAYER3_STR_BUFF_SIZE] = {0};
    char dft_dns[OMCI_LAYER3_STR_BUFF_SIZE] = "0.0.0.0";
	struct in_addr address;
#endif

	omci_ip_host_cfg_ptr new_iphost = NULL;
	if((me_info == NULL) || (omci_attr == NULL))
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] me_info is NULL\n", __FUNCTION__, __LINE__);
        return -1;
    }
    
    new_iphost = (omci_ip_host_cfg_ptr)me_info->attributes;
	

	if((new_iphost->ipOptions & IP_OPTION_DHCP_MASK) == 0)//DHCP disable, curAddr == addr
	{
		new_iphost->currentSecondaryDNS = new_iphost->secondaryDNS;
	}
	else//DHCP enable, curAddr is assigned by DHCP, if not,  undefined
	{
	
#ifdef TCSUPPORT_PON_IP_HOST
		if(omci_wan_get_attr(WAN_IF_TYPE_SEC_DNS,me_info->inst_id,ipAddr,sizeof(ipAddr)) != 0){
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get wanInfo curPrimaryDNS fail\n", __FUNCTION__, __LINE__);
			return -1;
		}
        else
       	{
       		strcpy(ipAddr,dft_dns);
       	}

		memset(&address, 0, sizeof(address));
		inet_aton(ipAddr, &address);
				
		new_iphost->currentSecondaryDNS = ntohl(address.s_addr);
#endif
	}
	
	return 0;
}


/*******************************************************************************************************************************
9.4.2: IP host performance monitoring history data

********************************************************************************************************************************/



/*******************************************************************************************************************************
9.4.4: TCP/UDP performance monitoring history data

********************************************************************************************************************************/

